package com.linktel.productionLine.service;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.linktel.productionLine.EasyExcel.dailyAttendance.model.WriteDailyAttendance;
import com.linktel.productionLine.EasyExcel.dailyPlanning.model.WriteDailyPlanning;
import com.linktel.productionLine.common.ErrorCode;
import com.linktel.productionLine.dao.DailyAttendanceDao;
import com.linktel.productionLine.dao.DailyPlanningDao;
import com.linktel.productionLine.dao.MonthlyPlanningDao;
import com.linktel.productionLine.entity.MonthlyPlanning;
import com.linktel.productionLine.entity.dto.dailyPlanning.DailyPlanningDTO;
import com.linktel.productionLine.entity.query.dailyPlanning.*;
import com.linktel.productionLine.exception.BusinessException;
import com.linktel.productionLine.util.MethodUtils;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 对 每日计划（日出勤基础数据、日计划产能和排产）的操作
 *
 * @Author HuangJiaHui
 * @Date 2023/8/25 10:26
 */
@Service
@AllArgsConstructor
public class DailyPlanningService {

    private DailyAttendanceDao dailyAttendanceDao;

    private DailyPlanningDao dailyPlanningDao;

    private MonthlyPlanningDao monthlyPlanningDao;

    private BaseStepService baseStepService;

    /**
     * 根据查询条件，返回日计划产能和排产列表
     *
     * @param listDailyPlanningQuery 请求封装类
     * @return 日计划产能和排产列表
     */
    public PageInfo<DailyPlanningDTO> listDailyPlanning(ListDailyPlanningQuery listDailyPlanningQuery) {
        String productionLineCode = listDailyPlanningQuery.getProductionLineCode();
        String keyStepCode = listDailyPlanningQuery.getKeyStepCode();
        String planningDate = listDailyPlanningQuery.getPlanningDate();
        Long commitUserId = listDailyPlanningQuery.getCommitUserId();
        int pageSize = listDailyPlanningQuery.getPageSize();
        int pageNum = listDailyPlanningQuery.getPageNum();
        if (commitUserId == null || commitUserId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "填写数据不完整，请重新填写");
        }
        Integer year = null;
        Integer month = null;
        if (planningDate != null && !"".equals(planningDate)) {
            Calendar calendar = MethodUtils.getCalendarByDate(planningDate);
            year = calendar.get(Calendar.YEAR);
            month = calendar.get(Calendar.MONTH) + 1;
        }
        PageHelper.startPage(pageNum, pageSize);
        List<DailyPlanningDTO> dailyPlanningDTOS = dailyPlanningDao.listDailyPlanning(productionLineCode, keyStepCode, year, month);
        return new PageInfo<>(dailyPlanningDTOS);
    }

    /**
     * 增加日计划产能和排产
     *
     * @param addDailyPlanningQuery 增加的日计划产能和排产
     * @return 是否新增成功
     */
    public Boolean addDailyPlanning(AddDailyPlanningQuery addDailyPlanningQuery) {
        String productionLineCode = addDailyPlanningQuery.getProductionLineCode();
        String keyStepCode = addDailyPlanningQuery.getKeyStepCode();
        LocalDate planningDate = addDailyPlanningQuery.getPlanningDate();
        Double targetRate = addDailyPlanningQuery.getTargetRate();
        Long currentUserId = addDailyPlanningQuery.getCurrentUserId();
        Integer capacity = addDailyPlanningQuery.getCapacity();
        Integer scheduling = addDailyPlanningQuery.getScheduling();
        if (productionLineCode == null || productionLineCode.equals("") || keyStepCode == null || keyStepCode.equals("") || planningDate == null || currentUserId == null || currentUserId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "填写数据不完整，请重新填写");
        }
        String keyStepName = baseStepService.getBaseStepNameByCode(keyStepCode);
        if (StringUtils.isEmpty(keyStepName)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        Long capacityAndSchedulingId = dailyPlanningDao.getCapacityAndSchedulingInfo(productionLineCode, keyStepCode, planningDate.toString(), currentUserId);
        if (capacityAndSchedulingId != null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "一条产线、一个关键工序，同一天只能有一条日计划产能和排产数据，不能重复添加");
        }
        isExistInMonthlyPlanning(productionLineCode, keyStepCode, planningDate, currentUserId);
        return dailyPlanningDao.addDailyPlanning(productionLineCode, keyStepCode, keyStepName, planningDate, targetRate, capacity, scheduling, currentUserId);

    }


    /**
     * 修改日计划产能和排产
     *
     * @param editDailyPlanningQuery 增加的日计划产能和排产信息封装
     * @return 是否修改成功
     */
    public Boolean editDailyPlanning(EditDailyPlanningQuery editDailyPlanningQuery) {
        Long id = editDailyPlanningQuery.getId();
        String productionLineCode = editDailyPlanningQuery.getProductionLineCode();
        String keyStepCode = editDailyPlanningQuery.getKeyStepCode();
        LocalDate planningDate = editDailyPlanningQuery.getPlanningDate();
        Double targetRate = editDailyPlanningQuery.getTargetRate();
        Long currentUserId = editDailyPlanningQuery.getCurrentUserId();
        Integer capacity = editDailyPlanningQuery.getCapacity();
        Integer scheduling = editDailyPlanningQuery.getScheduling();
        if (id == null || id <= 0 || productionLineCode == null || keyStepCode == null || planningDate == null || currentUserId == null || currentUserId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        isExistInMonthlyPlanning(productionLineCode, keyStepCode, planningDate, currentUserId);
        return dailyPlanningDao.editDailyPlanning(id, targetRate, capacity, scheduling, currentUserId);
    }

    /**
     * 删除日计划产能和排产
     *
     * @param deleteDailyPlanningQuery 删除的日计划产能和排产的封装
     * @return 是否删除成功
     */
    public Boolean deleteDailyPlanning(DeleteDailyPlanningQuery deleteDailyPlanningQuery) {
        Long id = deleteDailyPlanningQuery.getId();
        Long currentUserId = deleteDailyPlanningQuery.getCurrentUserId();
        if (id == null || id <= 0 || currentUserId == null || currentUserId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        return dailyPlanningDao.deleteDailyPlanning(id, currentUserId);
    }

    /**
     * 是否在月度规划中存在
     *
     * @param productionLineCode 产线编码
     * @param keyStepCode        关键工序编码
     * @param planningDate       计划日期
     * @param currentUserId      当前登录用户id
     */
    private void isExistInMonthlyPlanning(String productionLineCode, String keyStepCode, LocalDate planningDate, Long currentUserId) {
        Integer year = planningDate.getYear();
        Integer month = planningDate.getMonthValue();
        List<MonthlyPlanning> monthlyPlanningCapacityInfo = monthlyPlanningDao.getMonthlyPlanningCapacityInfo(productionLineCode, keyStepCode, year.toString(), month.toString(), currentUserId);
        if (CollectionUtils.isEmpty(monthlyPlanningCapacityInfo)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "请现在月度规划产能中添加相关数据");
        }
    }


    /**
     * 根据查询条件，返回日计划产能和排产列表，用WriteDailyPlanning对象封装
     *
     * @param listDailyPlanningQuery WriteDailyPlanning对象封装类
     * @return WriteDailyPlanning列表
     */
    public List<WriteDailyPlanning> downloadAttendanceDate(ListDailyPlanningQuery listDailyPlanningQuery) {
        String productionLineCode = listDailyPlanningQuery.getProductionLineCode();
        String keyStepCode = listDailyPlanningQuery.getKeyStepCode();
        String planningDate = listDailyPlanningQuery.getPlanningDate();
        Long commitUserId = listDailyPlanningQuery.getCommitUserId();
        if (commitUserId == null || commitUserId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "填写数据不完整，请重新填写");
        }
        Integer year = null;
        Integer month = null;
        if (planningDate != null && !"".equals(planningDate)) {
            Calendar calendar = MethodUtils.getCalendarByDate(planningDate);
            year = calendar.get(Calendar.YEAR);
            month = calendar.get(Calendar.MONTH) + 1;
        }
        List<DailyPlanningDTO> dailyPlanningDTOS = dailyPlanningDao.listDailyPlanning(productionLineCode, keyStepCode,year, month);
        return dailyPlanningDTOS.stream().map(item -> {
            WriteDailyPlanning writeDailyAttendance = new WriteDailyPlanning();
            BeanUtils.copyProperties(item, writeDailyAttendance);
            writeDailyAttendance.setPlanningDate(item.getPlanningDate().toString());
            return writeDailyAttendance;
        }).collect(Collectors.toList());
    }
}
